/*
 * Clase que contiene métodos estáticos, ejecuta funciones para valorar
 * la salida de un componente específico de acuerdo a una lista
 * de entrada de valores en la compuerta lógica
 */
package fuente.compuertas;

import estructuras.SLL;
import estructuras.SLLNode;

/**
 * @author Alexandre
 * @author Rodrigo
 * @author Gabriel
 * @author Jeremy
 */

public class CompuertasNEntradas {
    
    /**
     * Obtiene la salida de la compuerta lógica AND de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaAND(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadAND(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaAND(listamodif);    
        }    
    }
    /**
     * Obtiene el valor de salida de una compuerta AND con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    private static int tablaverdadAND(int pE1,int pE2){
        if(pE1==1 && pE2==1)
            return 1;
        return 0;     
    }
    ///////////////////////////////////////////////////////////////////////  
    
    /**
     * Obtiene la salida de la compuerta lógica OR de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaOR(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadOR(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaOR(listamodif);    
        }  
    }
    /**
     * Obtiene el valor de salida de una compuerta OR con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    private static int tablaverdadOR(int pE1,int pE2){
        if(pE1==1 || pE2==1)
            return 1;
        return 0;     
    }
    ///////////////////////////////////////////////////////////////////////  
    
    /** Obtiene la salida de la compuerta lógica NOR de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaNOR(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadNOR(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaNOR(listamodif);    
        }  
    }
    /**
     * Obtiene el valor de salida de una compuerta NOR con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    public static int tablaverdadNOR(int pE1,int pE2){
        if(pE1==0 && pE2==0)
            return 1;
        return 0;     
    }
    ///////////////////////////////////////////////////////////////////////  
    
    /** Obtiene la salida de la compuerta lógica NAND de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaNAND(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadNAND(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaNAND(listamodif);    
        }  
    }
    /**
     * Obtiene el valor de salida de una compuerta NAND con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    public static int tablaverdadNAND(int pE1,int pE2){
        if(pE1==1 && pE2==1)
            return 0;
        return 1;     
    }
    /////////////////////////////////////////////////////////////////////// 
    
    /** Obtiene la salida de la compuerta lógica XOR de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaXOR(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadXOR(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaXOR(listamodif);    
        }  
    }
    /**
     * Obtiene el valor de salida de una compuerta XOR con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    private static int tablaverdadXOR(int pE1,int pE2){
        if((pE1==1 && pE2==1) || (pE1==0 && pE2==0))
            return 0;
        return 1;     
    }
     ///////////////////////////////////////////////////////////////////////  
    
    /** Obtiene la salida de la compuerta lógica XNOR de acuerdo a una respectiva
     * lista de entradas.
     * @param pLista Lista de entradas para valorar sus salida
     * @return valor binario de salida de acuerdo a las entradas
     */
    public static int salidaXNOR(SLL pLista){
        SLLNode primernodo=pLista.getHead();
        if (primernodo.getNext()==null){
            return (int) primernodo.getElemento();     
        }
        else{
            SLL listamodif=pLista;
            int e1=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int e2=(int) listamodif.getHead().getElemento();
            listamodif.eliminaPorPosicion(1);
            int nuev_e1e2=tablaverdadXNOR(e1,e2);
            listamodif.meterFinal(nuev_e1e2);
            return salidaXNOR(listamodif);    
        }  
    }
    /**
     * Obtiene el valor de salida de una compuerta XNOR con dos entradas binarias.
     * @param pE1 entrada binaria
     * @param pE2 entrada binaria
     * @return Valor de salida calculado con sus entradas de parametros
     */
    private static int tablaverdadXNOR(int pE1,int pE2){
        if((pE1==1 && pE2==1) || (pE1==0 && pE2==0))
            return 1;
        return 0;     
    }
    ////////////////////////////////////////////////////////////////////
    
    /**
     * Obtiene el valor de salida de la compuerta NOT
     * @param pEntrada entada binaria
     * @return valor de salida (pEntrada negado, es decir, retorna 1 si pEntrada
     * es 0, de lo contrario retorna 0).
     */
    public static int salidaNOT (int pEntrada) {
        if (pEntrada == 1)
            return 0;
        else
            return 1;
    }
    ////////////////////////////////////////////////////////////////////
    
    /**
     * @param args the command line arguments
     */
   /* public static void main(String[] args) { 
        SLL listaSimple1 = new SLL();
       
        
        listaSimple1.meterFinal(1);
        listaSimple1.meterFinal(0);
        listaSimple1.meterFinal(0);
        listaSimple1.meterFinal(0);
        System.out.println("lista 1");
        listaSimple1.imprimir();
        int resultY= salidaAND(listaSimple1);
        System.out.println("Salida de Y");
        System.out.println(resultY);
//        int resultO= salidaOR(listaSimple1);
//        System.out.println("Salida de O");
//        System.out.println(resultO);
//        int resultNAND= salidaNAND(listaSimple1);
//        System.out.println("Salida de NAND");
//        System.out.println(resultNAND);
//        int resultNOR= salidaNOR(listaSimple1);
//        System.out.println("Salida de NOR");
//        System.out.println(resultNOR);
//        int resultXOR= salidaXOR(listaSimple1);
//        System.out.println("Salida de XOR");
//        System.out.println(resultXOR);
//        int resultXNOR= salidaXNOR(listaSimple1);
//        System.out.println("Salida de XNOR");
//        System.out.println(resultXNOR);
    }*/
}
